// Map comprehensive test suite
// Tests: creation, len(), insert(), index access [], contains(), remove()

func test_map_creation_and_len() {
    println("[Part 1] Testing Map creation and len() method")

    // Test empty maps
    println("  Testing empty maps...")
    var empty_map1 Map<String, int> = Map<String, int>{}
    assert(empty_map1.len() == 0, "Empty Map<String, int> should have len 0")

    var empty_map2 Map<int, int> = Map<int, int>{}
    assert(empty_map2.len() == 0, "Empty Map<int, int> should have len 0")

    var empty_map3 Map<int64, int64> = Map<int64, int64>{}
    assert(empty_map3.len() == 0, "Empty Map<int64, int64> should have len 0")
    println("  ✓ Empty maps: all passed")

    // Test literal creation - Map<String, int>
    println("  Testing literal creation - Map<String, int>...")
    var map1 Map<String, int> = Map<String, int>{"name": 100}
    assert(map1.len() == 1, "Map with 1 element should have len 1")

    var map2 Map<String, int> = Map<String, int>{
        "age": 30,
        "score": 95,
        "level": 5
    }
    assert(map2.len() == 3, "Map with 3 elements should have len 3")

    var map3 Map<String, int> = Map<String, int>{
        "a": 1, "b": 2, "c": 3, "d": 4, "e": 5
    }
    assert(map3.len() == 5, "Map with 5 elements should have len 5")
    println("  ✓ String->int maps: all passed")

    // Test literal creation - Map<int, int>
    println("  Testing literal creation - Map<int, int>...")
    var map4 Map<int, int> = Map<int, int>{1: 100, 2: 200}
    assert(map4.len() == 2, "Map with 2 int elements should have len 2")

    var map5 Map<int, int> = Map<int, int>{
        10: 100, 20: 200, 30: 300, 40: 400
    }
    assert(map5.len() == 4, "Map with 4 int elements should have len 4")
    println("  ✓ int->int maps: all passed")

    // Test literal creation - Map<int64, int64>
    println("  Testing literal creation - Map<int64, int64>...")
    var map6 Map<int64, int64> = Map<int64, int64>{100: 314, 200: 271}
    assert(map6.len() == 2, "Map with 2 int64 elements should have len 2")

    var map7 Map<int64, int64> = Map<int64, int64>{
        1000: 1, 2000: 2, 3000: 3
    }
    assert(map7.len() == 3, "Map with 3 int64 elements should have len 3")
    println("  ✓ int64->int64 maps: all passed")

    println("[Part 1] ✅ All creation and len() tests passed!")
    println()
}

func test_map_insert() {
    println("[Part 2] Testing insert() method")

    // Test insert into empty map - int keys
    println("  Testing insert with int keys...")
    var m1 Map<int, int> = Map<int, int>{}
    assert(m1.len() == 0, "New map should be empty")

    m1.insert(1, 100)
    assert(m1.len() == 1, "Map should have 1 element after insert")

    m1.insert(2, 200)
    m1.insert(3, 300)
    assert(m1.len() == 3, "Map should have 3 elements")
    println("  ✓ Basic insert: passed")

    // Test update existing key
    println("  Testing update existing key...")
    m1.insert(1, 999)
    assert(m1.len() == 3, "Updating existing key should not change length")
    println("  ✓ Update existing key: passed")

    // Test insert with string keys
    println("  Testing insert with String keys...")
    var m2 Map<String, int> = Map<String, int>{}
    m2.insert("first", 1)
    m2.insert("second", 2)
    m2.insert("third", 3)
    assert(m2.len() == 3, "Map should have 3 string elements")

    m2.insert("first", 100)
    assert(m2.len() == 3, "Updating string key should not change length")
    println("  ✓ String key insert: passed")

    // Test capacity growth
    println("  Testing capacity auto-growth (8 elements)...")
    var m3 Map<int, int> = Map<int, int>{}
    m3.insert(1, 1)
    m3.insert(2, 2)
    m3.insert(3, 3)
    m3.insert(4, 4)
    m3.insert(5, 5)
    m3.insert(6, 6)
    m3.insert(7, 7)
    m3.insert(8, 8)
    assert(m3.len() == 8, "Map should have 8 elements after capacity growth")
    println("  ✓ Capacity growth: passed")

    // Test insert into literal-created map
    println("  Testing insert into literal-created map...")
    var m4 Map<int64, int64> = Map<int64, int64>{100: 1, 200: 2}
    assert(m4.len() == 2, "Literal map should have 2 elements")
    m4.insert(300, 3)
    m4.insert(400, 4)
    assert(m4.len() == 4, "Map should have 4 elements after inserts")
    println("  ✓ Insert into literal map: passed")

    println("[Part 2] ✅ All insert() tests passed!")
    println()
}

func test_map_index_access() {
    println("[Part 3] Testing index access m[key]")

    // Test index access with int keys
    println("  Testing index access with int keys...")
    var m5 Map<int, int> = Map<int, int>{}
    m5.insert(10, 100)
    m5.insert(20, 200)
    m5.insert(30, 300)

    assert(m5[10] == 100, "m5[10] should be 100")
    assert(m5[20] == 200, "m5[20] should be 200")
    assert(m5[30] == 300, "m5[30] should be 300")
    println("  ✓ int key access: passed")

    // Test index access with string keys
    println("  Testing index access with String keys...")
    var m6 Map<String, int> = Map<String, int>{}
    m6.insert("first", 1)
    m6.insert("second", 2)
    m6.insert("third", 3)

    assert(m6["first"] == 1, "m6['first'] should be 1")
    assert(m6["second"] == 2, "m6['second'] should be 2")
    assert(m6["third"] == 3, "m6['third'] should be 3")
    println("  ✓ String key access: passed")

    // Test index access after update
    println("  Testing index access after update...")
    m5.insert(10, 999)
    assert(m5[10] == 999, "m5[10] should be updated to 999")
    println("  ✓ Access after update: passed")

    println("[Part 3] ✅ All index access tests passed!")
    println()
}

func test_map_contains() {
    println("[Part 4] Testing contains() method")

    // Test contains with int keys
    println("  Testing contains with int keys...")
    var m7 Map<int, int> = Map<int, int>{}
    m7.insert(10, 100)
    m7.insert(20, 200)
    m7.insert(30, 300)

    assert(m7.contains(10), "Map should contain key 10")
    assert(m7.contains(20), "Map should contain key 20")
    assert(m7.contains(30), "Map should contain key 30")
    assert(!m7.contains(40), "Map should not contain key 40")
    assert(!m7.contains(0), "Map should not contain key 0")
    println("  ✓ int key contains: passed")

    // Test contains with string keys
    println("  Testing contains with String keys...")
    var m8 Map<String, int> = Map<String, int>{}
    m8.insert("first", 1)
    m8.insert("second", 2)
    m8.insert("third", 3)

    assert(m8.contains("first"), "Map should contain key 'first'")
    assert(m8.contains("second"), "Map should contain key 'second'")
    assert(m8.contains("third"), "Map should contain key 'third'")
    assert(!m8.contains("fourth"), "Map should not contain key 'fourth'")
    assert(!m8.contains(""), "Map should not contain empty string key")
    println("  ✓ String key contains: passed")

    // Test contains on empty map
    println("  Testing contains on empty map...")
    var m9 Map<int, int> = Map<int, int>{}
    assert(!m9.contains(1), "Empty map should not contain any key")
    assert(!m9.contains(0), "Empty map should not contain any key")
    println("  ✓ Empty map contains: passed")

    println("[Part 4] ✅ All contains() tests passed!")
    println()
}

func test_map_remove() {
    println("[Part 5] Testing remove() method")

    // Test remove with int keys
    println("  Testing remove with int keys...")
    var m10 Map<int, int> = Map<int, int>{}
    m10.insert(10, 100)
    m10.insert(20, 200)
    m10.insert(30, 300)
    assert(m10.len() == 3, "Map should have 3 elements before remove")

    m10.remove(20)
    assert(m10.len() == 2, "Map should have 2 elements after removing one")
    assert(m10.contains(10), "Map should still contain key 10")
    assert(!m10.contains(20), "Map should not contain removed key 20")
    assert(m10.contains(30), "Map should still contain key 30")
    assert(m10[10] == 100, "Value for key 10 should still be 100")
    assert(m10[30] == 300, "Value for key 30 should still be 300")
    println("  ✓ int key remove: passed")

    // Test remove with string keys
    println("  Testing remove with String keys...")
    var m11 Map<String, int> = Map<String, int>{}
    m11.insert("first", 1)
    m11.insert("second", 2)
    m11.insert("third", 3)
    assert(m11.len() == 3, "Map should have 3 elements before remove")

    m11.remove("second")
    assert(m11.len() == 2, "Map should have 2 elements after removing one")
    assert(m11.contains("first"), "Map should still contain key 'first'")
    assert(!m11.contains("second"), "Map should not contain removed key 'second'")
    assert(m11.contains("third"), "Map should still contain key 'third'")
    println("  ✓ String key remove: passed")

    // Test remove non-existent key
    println("  Testing remove non-existent key...")
    var m12 Map<int, int> = Map<int, int>{}
    m12.insert(10, 100)
    assert(m12.len() == 1, "Map should have 1 element")

    m12.remove(999)
    assert(m12.len() == 1, "Map should still have 1 element after removing non-existent key")
    assert(m12.contains(10), "Map should still contain key 10")
    println("  ✓ Remove non-existent key: passed")

    // Test remove all elements
    println("  Testing remove all elements...")
    var m13 Map<int, int> = Map<int, int>{}
    m13.insert(10, 100)
    m13.insert(20, 200)
    m13.insert(30, 300)

    m13.remove(10)
    m13.remove(20)
    m13.remove(30)
    assert(m13.len() == 0, "Map should be empty after removing all elements")
    assert(!m13.contains(10), "Map should not contain key 10")
    assert(!m13.contains(20), "Map should not contain key 20")
    assert(!m13.contains(30), "Map should not contain key 30")
    println("  ✓ Remove all elements: passed")

    println("[Part 5] ✅ All remove() tests passed!")
    println()
}
